<template>
  <div class="hello">
    <h1>事件Mod案例</h1>
    <el-button type="" @click="onHTML">*HTML页面引用</el-button>
    <el-button type="" @click="onHTML2()">*HTML2页面引用</el-button>
    <el-button type="" @click="onHTML2(3)">*HTML3页面引用</el-button>
    <el-button type="" @click="onHTML2(4)">测试布局页面</el-button>
	<el-button type="" @click="openHierarchy">使用布局函数页面</el-button>
    <el-button type="" @click="toJSON">导出数据</el-button>
    <el-button type="" @click="add">添加节点</el-button>
    <el-button type="" @click="add2">添加上游节点</el-button>
    <el-button id="myButton">My button</el-button>
    <el-switch v-model="showFlag" active-color="#13ce66" inactive-color="#ff4949">
    </el-switch><span>隐藏节点</span>
    <button data-tippy-content="Tooltip" disabled>Text</button>

    <!-- Wrapper <span> will work -->
    <span data-tippy-content="Tooltip" tabindex="0">
      <button disabled>Text</button>
    </span>
    <el-drawer :title="title" :visible.sync="drawer" :direction="direction" :before-close="handleClose">
      <!-- <span>我来啦!</span> -->
      <div v-show="nodeInfo.text">内容信息：<span>{{nodeInfo.text}}</span></div>
      <div v-if="nodeInfo.parent">父节点ID：<span>{{nodeInfo.parent.id}}</span></div>
      <div v-if="nodeInfo.parent">父节点名称：<span>{{nodeInfo.parent.data.title}}</span></div>

    </el-drawer>

    <div id="container-11">
      <div id="parent">
        <button aria-expanded="false">Text</button>
      </div>
    </div>
    <div id="minimapContainer"></div>
    <div id="top">
      <div class="d1">
        <div class="textId">dsada</div>
        <div @click.stop="test">我是按钮</div>
        <button onClick="a1()">22222211111</button>
      </div>
    </div>

  </div>
</template>


<script>
window.a1 = () => {
  alert();
  event.stopPropagation();
};
var list = [];
import {
  Shape,
  Graph,
  DataUri,
  minimapContainer,
  SimpleNodeView,
} from "@antv/x6";
import x6MainFn from "@/components/mod/x6Main/index.js";
import {
  addBtnChildrenTool,
  addBtnParentTool,
  decreaseBtnChildrenTool,
} from "@/components/mod/x6Main/tools.js";

import actionMod from "@/components/mod/html/actionMod";
import Mock from "mockjs";
// import tippy from "tippy.js";
// import "tippy.js/dist/tippy.css"; // optional for styling
// import "tippy.js/animations/scale.css";
// import "tippy.js/themes/light.css";
var mainFn = {};

export default {
  name: "containerMind",
  data() {
    return {
      graph: "",
      title: "",
      nodeInfo: {},
      drawer: false,
      direction: "rtl",
      rootId: "",
      showFlag: true,
      data: {
        nodes: [],
        // 边
        edges: [],
      },
      ranksep: 100,
      nodesep: 25,
    };
  },
  created() {
    this.initEdeg();
  },
  mounted() {
    this.init();
    window.getData = this.getData();
    tippy("#myButton", {
      content: "My tooltip!----!",
      placement: "top-start",
      arrow: true,
      animation: "scale",
      theme: "light",
      trigger: "click",
      interactive: true,
    });
  },
  methods: {
    test() {
      alert();
    },
    onHTML() {
      let data = localStorage.toJSON;
      if (data) {
        window.open("/html");
      } else {
        this.$message.success("创建数据后跳转HTML页面");
        this.toJSON();
        setTimeout(() => {
          window.open("/html");
        }, 1500);
      }
    },
    onHTML2(strnum) {
      let data = localStorage.toJSON;
      if (data) {
        console.log("num", strnum);
        let str = strnum ? "?str=" + strnum : "";
        window.open("/html2" + str);
      } else {
        this.$message.success("创建数据后跳转HTML页面");
        this.toJSON();
        setTimeout(() => {
          window.open("/html2");
        }, 1500);
      }
    },
	openHierarchy(){
		console.log("openHierarchy  -- 使用布局函数")
		// window.open("/openHierarchy");
		alert("手动打开 public/X6TestData.html  页面")
	},
    //导出数据
    toJSON() {
      let data = this.graph.toJSON();
      console.log("toJSON", data);
      let arr = { nodes: [], edges: [] };
      data.cells.map((item) => {
        if (item.shape.indexOf("edge") > -1) {
          let obj = {};
          for (const key in item) {
            if (Object.hasOwnProperty.call(item, key)) {
              obj[key] = item[key];
            }
          }
          arr.edges.push(item);
        } else {
          let obj = {};
          for (const key in item) {
            if (Object.hasOwnProperty.call(item, key)) {
              obj[key] = item[key];
            }
          }
          arr.nodes.push(item);
        }
      });
      console.log("arr", arr);
      localStorage.setItem("toJSON", JSON.stringify(arr));
    },
    initEdeg() {
      Graph.registerEdge(
        "custom-edge-label",
        {
          inherit: "edge",
          defaultLabel: {
            markup: [
              {
                tagName: "rect",
                selector: "body",
              },
              {
                tagName: "text",
                selector: "label",
              },
            ],
            attrs: {
              label: {
                fill: "#000",
                fontSize: 14,
                textAnchor: "middle",
                textVerticalAnchor: "middle",
                pointerEvents: "none",
              },
              body: {
                ref: "label",
                fill: "#ffd591",
                stroke: "#ffa940",
                strokeWidth: 2,
                rx: 4,
                ry: 4,
                refWidth: "140%",
                refHeight: "140%",
                refX: "-20%",
                refY: "-20%",
              },
            },
            position: {
              distance: 0.5,
              options: {
                absoluteDistance: true,
                reverseDistance: true,
              },
            },
          },
        },
        true
      );
    },
    handleClose(done) {
      this.drawer = false;
    },
    getData() {
      return this.data;
    },
    clickAction() {
      this.graph.on("node:click", ({ e, x, y, node, view }) => {
        // console.log("node 节点:click", e, x, y, node, view);
        // this.drawer = true;
        console.log("node", node);
        node.data.info = { name: "1231dd" };
        this.nodeInfo = {};
        this.title = node.data.title;
        this.nodeInfo.text = node.data.text;
        this.nodeInfo.parent = node.parent;
        let template = document.getElementById("top");
        let str = template.innerHTML;
        let instances1 = tippy("#modBody" + node.id, {
          appendTo: () => document.body,
          placement: "top-start",
          arrow: true,
          animation: "scale",
          theme: "light",
          trigger: "click",
          content: str,
          allowHTML: true,
          interactive: true, //交互
          // appendTo: "parent",
        });

        for (let i = 0; i < list.length; i++) {
          let element = list[i];

          element.destroy();
        }

        list.length = 0;
        list.push(instances1[0]);
      });
      this.graph.on("edge:click", ({ e, x, y, edge, view }) => {
        // console.log("	edge 边:click", e, x, y, edge, view);
        alert("边线:click");
      });
      this.graph.on("blank:click", ({ e, x, y }) => {
        // console.log("blank 画布空白区域:click", e, x, y);
        this.drawer = false;
      });

      this.graph.on("node:mouseenter", ({ e, x, y, node }) => {
        console.log("node:mouseenter 进入", e, x, y, node);
        let data = node.getData();

        if (data.root) {
          //根节点处理
          this.getRootTools(node);
        } else if (data.dir == "down") {
          //下游节点处理
          this.getDownTools(node);
        } else if (data.dir == "up") {
          //上游节点处理
          this.getUpTools(node);
        }
      });
      this.graph.on("node:mouseleave", ({ e, x, y, node }) => {
        //移出
        console.log("node:mouseleave 移出", e, x, y, node);
        node.removeTools();
      });
    },
    add(node) {
      let me = this;
      let nodeObj = this.createNode();
      let nodes = this.graph.getNodes();
      let parentNode = {};
      let parentId = "";
      if (node) {
        //有指定节点就使用指定节点
        console.log("node", node);
        parentId = node.id;
        parentNode = node;
        nodeObj.parent = parentId;
      } else {
        let leafNode = this.graph.getLeafNodes(); //所有叶子节点
        // console.log("leafNode", leafNode);
        let num = Mock.mock(`@natural(0, ${leafNode.length - 1})`);
        parentId = nodes[num - 0].id;
        // parentNode.children = nodeObj.id;
        parentNode = this.graph.getCellById(parentId);
        // nodeObj.setParent(parentNode);
        nodeObj.parent = parentId;
      }

      this.data.nodes.push(nodeObj);

      console.log("this.data.nodes", this.data.nodes);

      this.data.edges.push({
        source: parentId,
        target: nodeObj.id,
        shape: "custom-edge-label",
        // labels: ["步骤过程"],
        attrs: {
          line: {
            stroke: "#A2B1C3",
            strokeWidth: 2,
          },
        },
      });

      this.layout();
      let tempNode = this.graph.getCellById(nodeObj.id);
      parentNode.addChild(tempNode);
    },
    //给父节点插入
    add2(node) {
      let me = this;
      let nodeObj = this.createNode(Mock.mock("@id"), false, "up");

      // nodeObj.children = node.id;
      this.data.nodes.push(nodeObj);

      this.data.edges.push({
        source: nodeObj.id,
        target: node.id,
        // labels: ["步骤过程"],
        attrs: {
          line: {
            stroke: "#A2B1C3",
            strokeWidth: 2,
          },
        },
      });
      this.layout();
      let parentNode = this.graph.getCellById(nodeObj.id);
      let childNode = this.graph.getCellById(node.id);
      childNode.insertTo(parentNode);
    },
    //显示相关节点和边
    showCell(node, dir) {
      let id = node.id;
      findNode(id);
      function findNode(id) {
        let edges = mainFn.getEdges();
        edges.map((item) => {
          if (dir == "down") {
            //处理子节点
            let source = item.source.cell;
            if (source == id) {
              let target = item.target.cell;
              let targetNode = mainFn.getById(target);
              targetNode.data.showFlag = true;
              //console.log("targetNode", targetNode);
              targetNode.show();
              findNode(targetNode.id);
            }
          } else if (dir == "up") {
            //处理父节点
            let target = item.target.cell;
            if (target == id) {
              let source = item.source.cell;
              let sourceNode = mainFn.getById(source);
              sourceNode.data.showFlag = true;
              console.log("sourceNode", sourceNode);
              sourceNode.show();
              findNode(sourceNode.id);
            }
          }
        });
      }
      node.removeTools();
    },
    //隐藏相关节点和边
    hideCell(node, dir) {
      let id = node.id;
      findNode(id);
      function findNode(id) {
        let edges = mainFn.getEdges();
        edges.map((item) => {
          if (dir == "down") {
            //处理子节点
            let source = item.source.cell;
            if (source == id) {
              let target = item.target.cell;
              let targetNode = mainFn.getById(target);
              targetNode.data.showFlag = false;
              console.log("targetNode", targetNode);
              targetNode.hide();
              findNode(targetNode.id);
            }
          } else if (dir == "up") {
            //处理父节点
            let target = item.target.cell;
            if (target == id) {
              let source = item.source.cell;
              let sourceNode = mainFn.getById(source);
              sourceNode.data.showFlag = false;
              console.log("sourceNode", sourceNode);
              sourceNode.hide();
              findNode(sourceNode.id);
            }
          }
        });
      }
      node.removeTools();
    },
    //布局函数
    layout() {
      let me = this;
      me.graph.freeze();
      let hideNodeList = mainFn.nodeIsShowFn(); //获取要隐藏的节点
      const { DagreLayout } = window.layout;
      const dagreLayout = new DagreLayout({
        type: "dagre",
        rankdir: "LR",
        align: "",
        ranksep: me.ranksep,
        nodesep: me.nodesep,
        controlPoints: true,
      });
      const newModel = dagreLayout.layout(this.data);
      this.graph.fromJSON(newModel);
      //隐藏对应节点
      for (const key in hideNodeList) {
        if (hideNodeList.hasOwnProperty.call(hideNodeList, key)) {
          const element = hideNodeList[key];
          element.map((item) => {
            let node = mainFn.getById(item);
            node.hide();
          });
        }
      }
      me.graph.unfreeze();
    },

    init() {
      let pane9 = document.getElementById("pane-9");
      let me = this;
      console.log("SimpleNodeView", SimpleNodeView);
      const graph = new Graph({
        container: document.getElementById("container-11"),
        width: document.documentElement.clienth,
        height: 900,
        scroller: {
          enabled: true, //滚动
          className: "my-scroller",
        },
        panning: {
          // enabled: true, //画布可以平移
          //还可以配置 eventTypes 来设置触发画布拖拽的行为，支持 leftMouseDown、 rightMouseDown、mouseWheel，默认为 ['leftMouseDown'] 。
          eventTypes: ["leftMouseDown", "rightMouseDown", "mouseWheel"],
        },
        // interacting: { nodeMovable: false },
        // async: true,
        // frozen: true,
        // scroller: true,
        // interacting: false,
        background: {
          color: "#fffbe6", // 设置画布背景颜色
        },
        // selecting: {
        //   enabled: true,
        //   rubberband: true,
        //   showNodeSelectionBox: true,
        // },
        minimap: {
          enabled: true,
          container: minimapContainer,
          graphOptions: {
            async: true,
            getCellView(cell) {
              // 用指定的 View 替换节点默认的 View
              if (cell.isNode()) {
                return SimpleNodeView;
              }
            },
            createCellView(cell) {
              // 在小地图中不渲染边
              if (cell.isEdge()) {
                return null;
              }
            },
          },
        },
        grid: {
          size: 10, // 网格大小 10px
          visible: true, // 渲染网格背景
        },
      });

      this.initData(5);

      this.graph = graph;
      mainFn = x6MainFn(graph);
      this.layout();

      this.clickAction();
      window.graph = graph;
      //初始化模拟数据增加关系
      let rootNode = this.graph.getCellById(this.rootId);
      //初始化子节点关系
      this.data.edges.map((item) => {
        let id = item.target;
        let childNode = this.graph.getCellById(id);
        rootNode.addChild(childNode);
      });
    },
    initData(num = 1) {
      let rootId = "";

      for (let i = 0; i < num; i++) {
        let root = false;
        let id = Mock.mock("@id");
        if (i == 0) {
          rootId = id;
          root = true;
          this.rootId = rootId;
        }

        let nodeObj = this.createNode(id, root);
        this.data.nodes.push(nodeObj);
        if (i > 0) {
          this.data.edges.push({
            source: rootId,
            target: id,
            // labels: ["步骤过程"],
            attrs: {
              line: {
                stroke: "#A2B1C3",
                strokeWidth: 2,
              },
            },
          });
        }
        this.data.edges.map((item, i) => {
          item.zIndex = -1000;
        });
      }
    },
    createNode(id = Mock.mock("@id"), root = false, dir = "down") {
      let me = this;
      let type = Mock.mock('@pick(["tab", "api"])');
      let title = type == "tab" ? "表" : "API";
      return {
        id: id,
        width: 200,
        height: 60,
        shape: "html",
        data: {
          id,
          time: new Date().toString(),
          type: type,
          dir,
          showFlag: true,
          // title: Mock.mock("@title(1, 2)"),
          rootId: me.rootId,
          root: root,
          title: title,
          text: [Mock.mock("@name(1)")],
        },

        html: {
          render(node) {
            const data = node.getData();
            return actionMod(data);
          },
          shouldComponentUpdate(node) {
            // 控制节点重新渲染
            return node.hasChanged("data");
          },
        },
      };
    },
    /**
     * 根节点添加工具
     * @param {*} node 对象
     */
    getRootTools(node) {
      // node.addTools(addBtnParentTool(this.add2));
      // node.addTools(addBtnChildrenTool(this.add));
      this.getDownTools(node);
      this.getUpTools(node);
    },
    /**
     * 下游节点添加工具
     * @param {*} node 对象
     */
    getDownTools(node) {
      if (this.showFlag) {
        //开始隐藏节点

        let childrenFlag = mainFn.getEdges().find((item) => {
          return item.source.cell == node.id;
        });
        console.log("childrenFlag", childrenFlag);
        if (!childrenFlag) {
          //没有子节点
          node.addTools(addBtnChildrenTool(this.add));
        } else {
          //有子节点 使用显示或隐藏
          let child = mainFn.getById(childrenFlag.target.cell);
          console.log("child", child);
          let item = child[0] ? child[0] : child;
          if (item.visible) {
            //添加隐藏工具
            node.addTools(decreaseBtnChildrenTool(this.hideCell));
          } else {
            //添加显示工具
            node.addTools(addBtnChildrenTool(this.showCell));
          }
        }
      } else {
        node.addTools(addBtnChildrenTool(this.add));
      }
    },
    /**
     * 上游节点添加工具
     * @param {*} node 对象
     */
    getUpTools(node) {
      node.addTools(addBtnParentTool(this.add2));
    },
  },
};
</script>

<style scoped lang="scss">
#container-11 {
  width: 100%;
  height: 100%;
}
.topic-image {
  visibility: hidden;
  cursor: pointer;
}
.x6-node:hover .topic-image {
  visibility: visible;
}
.x6-node-selected rect {
  stroke-width: 2px;
}
.d1 {
  width: 100px;
  height: 100px;
  background-color: rebeccapurple;
  font-size: 18px;
  // pointer-events: none;
  div {
    line-height: 18px;
    border-bottom: 1px solid red;
    pointer-events: none;
  }
}
</style>
